<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>5.promise练习3.html</title>
</head>
<body>
    
</body>
<script>
    const PROMISE_STATUS_PENDING = 'pending'
    const PROMISE_STATUS_FULFILLED = 'fulfilled'
    const PROMISE_STATUS_REJECTED = 'rejected'

    class MyPromise1 {
        constructor(executor) {
            this.status = PROMISE_STATUS_PENDING
            this.result = undefined
            this.reason = undefined
            this.onFufilledFns = []
            this.onRejectedFns = []

            const resolve = (result) => {
                if(this.status !== PROMISE_STATUS_PENDING) return
                queueMicrotask(() => {
                    this.status = PROMISE_STATUS_FULFILLED
                    this.result = result
                    this.onFufilledFns.forEach(fn => fn())
                })            
            }
            const reject = (reason) => {
                if(this.status !== PROMISE_STATUS_PENDING) return
                queueMicrotask(() => {
                    this.status = PROMISE_STATUS_REJECTED
                    this.reason = reason
                    this.onRejectedFns.forEach(fn => fn())
                })
                            }
            executor(resolve,reject)            
        }
        then(onFullfillFn, onRejectedFn) {
            return new MyPromise1((resolve, reject) => {
                if(this.status === PROMISE_STATUS_FULFILLED, onFullfillFn){
                    let result = onFullfillFn(this.result)
                    resolve(result)
                }
                if(this.status === PROMISE_STATUS_REJECTED, onRejectedFn){
                    let reason = onRejectedFn(this.reason)
                    reject(reason)
                }
                if(this.status === PROMISE_STATUS_PENDING) {
                    if(onFullfillFn){
                        this.onFufilledFns.push(() => {
                            let result = onFullfillFn(this.result)
                            resolve(result)
                        })
                    }
                    if(onRejectedFn){
                        this.onRejectedFns.push(() => {
                            let reason = onRejectedFn(this.reason)
                            reject(reason)
                        })
                    }
                }
            })
        }
        catch(onRejectedFn) {
            return this.then(undefined,onRejectedFn)
        }
        finally(onFinally) {
            this.then(() => {
                onFinally()
            },() => {
                onFinally()
            })
        }
        static resolve(result) {
            return new MyPromise1(resolve => resolve(result))
        }
        static reject(reason) {
            return new MyPromise1((undefined, reject) => reject(reason))
        }
    }

    // let p1 = new MyPromise1((resolve, reject) => {
    //     resolve('第一段内容')
    //     return '传入到then中的内容'
    // }).then(res => {
    //     console.log('res:', res)
    // })   



    function MyPromise2(executor) {
        this.stauts = PROMISE_STATUS_PENDING
        this.result = undefined
        this.reason = undefined
        this.onFulfiledFns = []
        this.onRejectedFns = []
        const resolve = (result) => {
            if(PROMISE_STATUS_PENDING !== this.stauts) return
            this.status = PROMISE_STATUS_FULFILLED
            this.result = result
            this.onFulfiledFns.forEach(fn => fn())
        }
        const reject = (reason) => {
            if(PROMISE_STATUS_PENDING !== this.stauts) return
            this.status = PROMISE_STATUS_REJECTEDs
            this.reason = reason
            this.onRejectedFns.forEach(fn => fn())
        }
        executor(resolve, reject)
    }

    MyPromise2.prototype.then = function(onFullfillFn, onRejectedFn) {        
        return new MyPromise2(
            // (resolve, reject) => 
            function(resolve, reject)
            {
            console.log('this:', this)
            if(PROMISE_STATUS_FULFILLED === this.status && onFullfillFn){
                
            }
            if(PROMISE_STATUS_REJECTED === this.status && reject){

            }
            
        })
    }

    new MyPromise2(() => {
        return '消息'
    }).then(res => {
        console.log('res:', res)
    })
</script>
</html>